(function(window, $, $$path) {
  'use strict';

  var getRealPath = function getRealPath(url) {
    return (/^http(s)?:\/\/.+/.test(url) || url.indexOf($$path) > -1 ? url : url.slice(0, 1) === '/' ? $$path + url : $$path + '/' + url
    );
  };
  var isBody = function isBody(target) {
    var lower = function lower(input) {
      return String.prototype.toLowerCase.call(input);
    };
    var type = $.type(target);

    return type === 'string' ? lower(target) === 'body' : type === 'object' ? 'jquery' in target && lower(target[0].tagName) === 'body' || target === document.body : false;
  };

  var SETTER_REQUEST = {
    timeout : 0,
    type    : 'GET',
    cache   : false,
    dataType: 'json'
  };
  var SETTER_RESPONSE = {
    msgName   : 'msg', // 状态信息的字段名称
    dataName  : 'data', // 数据详情的字段名称
    statusName: 'success', // 数据状态的字段名称
    statusCode: {
      ok          : 200, // 数据状态一切正常的状态码
      logout      : '00029998', // 登录状态失效的状态码
      exception   : 602, // 异常状态 600 以上为自定义
      networkbreak: 0 // 网络中断
    }
  };

  var Http = function Http(options, setting) {
    this.v = '1.0.4';
    this.__PAGE__ = {
      login: $$path + '/login'
    };
    this.config = null;
    this.setter = null;
    this._handleConfig(options);
    this._handleSetter(setting);
  };

  Http.index = -1;

  Http.prototype.load = function() /* options */{
    layui.use('layer', function() {
      var layer = layui.layer;

      Http.index = layer.load(2, {
        shade: [0.6, '#fff']
      });
    });
  };

  Http.prototype.removeLoad = function() {
    layui.use('layer', function() {
      layui.layer.close(Http.index);
    });
  };

  Http.prototype._handleSetter = function(options) {
    var _options = this.setter || {
      target   : null,
      text     : null,
      showShade: true,
      showLoad : true
    };
    var type = $.type(options);

    if (type === 'string') {
      _options.target = options;
    } else if (type === 'boolean') {
      _options.showLoad = options;
    } else if (type === 'object') {
      var showShade = options.showShade;

      delete options.showShade;
      $.extend(_options, options);

      _options.showLoad = isBody(_options.target);

      if (showShade) {
        _options.showShade = showShade;
      }
    } else {
      _options.showShade = isBody(_options.target);
    }

    this.setter = _options;
  };

  Http.prototype._handleConfig = function(options) {
    var _options = this.config || {
      url     : '',
      type    : SETTER_REQUEST.type,
      data    : {},
      cache   : SETTER_REQUEST.cache,
      timeout : SETTER_REQUEST.timeout,
      dataType: SETTER_REQUEST.dataType,
      headers : {
        isIE: !!layui.device().ie
      }
    };

    if ($.type(options) === 'string') {
      _options.url = options;
    } else if ($.type(options) === 'object') {
      $.extend(_options, options);
    }

    var path = _options.url;
    _options.url = getRealPath(path);

    this.config = _options;
  };

  Http.prototype._isStandardException = function(data) {
    if ($.isEmptyObject(data)) return false; // 非标准异常

    var message = data.message;
    var code = data.code;
    var mark = data.mark;

    if (code === SETTER_RESPONSE.statusCode.exception) {
      top.location.href = this.__PAGE__.login;
    }

    if (mark === 'error') {
      this.hint(message + '\uFF1A<cite>' + code + '</cite>');
    }

    return true; // 标准异常
  };

  Http.prototype.hint = function(content, options) {
    var _frame = top.frame;
    var _layer = top.layer;

    if (_frame && $.isFunction(_frame.hint)) {
      _frame.hint(content, options);
    } else if (_layer && $.isFunction(_layer.alert)) {
      _layer.alert(content, options);
    } else if (alert && $.isFunction(alert)) {
      alert(content);
    }
  };

  Http.prototype.fetch = function() /*, HttpSetting */{
    var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : $.noop;

    var that = this;
    var args = Array.prototype.slice.call(arguments);
    var argsLength = args.length;
    var setter = this.setter;

    var options = that.config;
    if (!options.url) return;

    var _success = options.success;
    var _error = options.error;
    var _complete = options.complete;

    delete options.success;
    delete options.error;
    delete options.complete;

    var showLoad = setter.showLoad;

    if (argsLength === 2) {
      var type = $.type(args[1]);
      type === 'string' ? setter.target = args[1] : showLoad = !!args[1];

      if (type === 'object') {
        'target' in args[1] && (setter.target = args[1]['target']);
        'showLoad' in args[1] && (showLoad = args[1]['showLoad']);
      }
    } else if (argsLength >= 3) {
      $.type(args[1]) === 'string' ? (setter.target = args[1], showLoad = !!args[2]) : (setter.target = args[2], showLoad = !!args[1]);
    }

    showLoad && that.load();

    var deffer = $.ajax($.extend({
      success: function success(response) {
        showLoad && that.removeLoad();
        $.isFunction(_success) && _success(response);
      },
      error: function error(response) {
        showLoad && that.removeLoad();
        $.isFunction(_error) && _error(response);
      },
      complete: function complete(response, status) {
        showLoad && that.removeLoad();

        var data = null;
        var res = null;

        if (response.status === SETTER_RESPONSE.statusCode.networkbreak) {
          that.hint('\u5F53\u524D\u7F51\u7EDC\u4FE1\u53F7\u4E0D\u597D\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC');
          return false;
        }

        try {
          res = options.dataType === 'json' ? JSON.parse(response.responseText) : response.responseText;
        } catch (e) {
          //
        }

        if (res) {
          if ($.isPlainObject(res) && SETTER_RESPONSE.statusName in res) {
            // 新版本的返回体
            data = res[SETTER_RESPONSE.dataName];

            if (!res[SETTER_RESPONSE.statusName]) {
              if (!that._isStandardException(data)) {
                var errText = ['<cite>\u9519\u8BEF\u4FE1\u606F: </cite>' + (res[SETTER_RESPONSE.msgName] || '返回状态码异常'), '<br><cite>URL: </cite>' + options.url].join('');
                that.hint(errText);
              }
            }
          } else {
            // 旧版本返回体
            data = res;
          }
        } else {
          that.hint('\u8FD4\u56DE\u53C2\u6570\u65E0\u6CD5\u8F6C\u6362\u6210\u6807\u51C6\u6570\u636E\u683C\u5F0F');
          console && console.log('参数: \n', options);
          console && console.log('返回结果：\n', response.responseText);
          return false;
        }

        $.isFunction(_complete) && _complete.apply(this, arguments);

        var ret = Array.prototype.slice.call(arguments);
        ret.unshift(res);
        $.isFunction(callback) && callback.apply(that, ret);

        if (status === 'timeout') {
          var timer = setTimeout(function() {
            that.hint('\u7F51\u7EDC\u8BF7\u6C42\u8D85\u65F6');
            clearTimeout(timer);
            deffer.abort();
          }, 200);
        }
      }
    }, options));
    return deffer;
  };

  Http.prototype.ajax = function(options, setting) {
    var _options = { type: 'POST' };
    var type = $.type(options);

    if (type === 'string') {
      _options.url = options;
    } else if (type === 'object') {
      $.extend(true, _options, options);
    }
    this._handleConfig(_options);
    this._handleSetter(setting);

    return this.fetch();
  };

  window.$$http = new Http();

  var isDev = /dev|test/.test(window.$$env);
  layui.config({
    base   : (window.$$path || '') + '/js/lay-ext/',
    version: isDev ? new Date().getTime() : false
  }).extend({
    setter    : '../config',
    index     : '../index',
    gwzh      : '../core/gwzh' + (isDev ? '' : '.min'),
    view      : '../core/view' + (isDev ? '' : '.min'),
    entity    : 'entity',
    choose    : 'choose',
    treeselect: 'treeselect',
    attach    : 'attach/index',
    toolbar   : 'toolbar',
    validate  : 'validate',
    helper    : 'helper',
    Http      : 'http',
    store     : 'store',
    affix     : 'affix',
    more      : 'more'
    // 入口文件
  }).use('index').data('dev', isDev);

  window.openWaitProcess = window.openWaitProcess || function() {
    if (top !== self && top.Math !== Math && typeof top.openWaitProcess === 'function') top.openWaitProcess();

    var frame = window.frame;
    if (!frame) return;
    
    var tab = frame.tab;
    var thisLayId = tab.getCurrentId();

    tab.add(frame.cache['tab_will']).refresh().close(thisLayId);
  };
  
  window.openUploadPage = window.openUploadPage || function() {
    if (top !== self && top.Math !== Math && typeof top.openUploadPage === 'function') top.openUploadPage();

    var frame = window.frame;
    if (!frame) return;
    
    layui.use(['view'],function () {
      layui.view.alert({
        content: '需要下载打印控件，是否现在去下载？',
        yes: function() {
          frame.openTab(frame.cache['tab_download']);
        }
      });
    });
  };

// eslint-disable-next-line no-undef
}(window, $, $$path));
